#include "AELogManager.hpp"

template<> arete::io::AELogManager* Ogre::Singleton<arete::io::AELogManager>::msSingleton = 0;

BEGIN_ARETE_NAMESPACE(io)

	AELogManager::AELogManager(void) :
	m_log_manager(NULL)
{
}

AELogManager::~AELogManager(void)
{
	m_log_manager.reset();
	m_log_manager = NULL;
}

void AELogManager::initialize( const string& _root)
{
	m_log_manager = std::make_shared<Ogre::LogManager>();

	Ogre::LogManager::getSingleton().setLogDetail(Ogre::LL_LOW);

	Ogre::Log* ogre = Ogre::LogManager::getSingleton().createLog(_root + "orge.log",true,true);
	ogre->setTimeStampEnabled(true);
	m_logs["ogre"] = ogre;

	Ogre::Log* def = Ogre::LogManager::getSingleton().createLog(_root + "uw.log",false,true);
	def->setTimeStampEnabled(true);
	def->setLogDetail(Ogre::LL_LOW);
	m_logs["default"] = def;
}

void AELogManager::registerScriptLoggers( asIScriptEngine* _eng)
{
	_eng->RegisterGlobalFunction("void warn(const string &in)",asMETHOD(AELogManager,warn),asCALL_THISCALL_ASGLOBAL,this);
	_eng->RegisterGlobalFunction("void error(const string &in)",asMETHOD(AELogManager,error),asCALL_THISCALL_ASGLOBAL,this);
	_eng->RegisterGlobalFunction("void info(const string &in)",asMETHOD(AELogManager,info),asCALL_THISCALL_ASGLOBAL,this);
	_eng->RegisterGlobalFunction("void print(const string &in)",asMETHOD(AELogManager,print),asCALL_THISCALL_ASGLOBAL,this);
}

void AELogManager::createLog( const string& _dir, const string& _name)
{
	m_logs[_name] = Ogre::LogManager::getSingleton().createLog(_dir + _name,false,true);
}

void AELogManager::destroyLog( const string& _name)
{
	Ogre::map<string, Ogre::Log*>::iterator iter = m_logs.find(_name);
	if(iter != m_logs.end())
	{
		Ogre::LogManager::getSingleton().destroyLog(m_logs[_name]);
		m_logs.erase(iter);
	}
}

void AELogManager::log( ELOG_LEVEL _level, const string& _msg, const string& _log /*= "default"*/ )
{
	string msg;
	Ogre::LogMessageLevel level;

	switch(_level)
	{
	case ELOG_LEVEL::ELL_NONE:
		msg = _msg;
		level = Ogre::LML_CRITICAL;
		break;

	case ELOG_LEVEL::ELL_INFO:
		msg = "[INFO] " + _msg;
		level = Ogre::LML_TRIVIAL;
		break;

	case ELOG_LEVEL::ELL_WARN:
		msg = "[WARN] " + _msg;
		level = Ogre::LML_NORMAL;
		break;

	case ELOG_LEVEL::ELL_ERROR:
		msg = "[ERROR] " + _msg;
		level = Ogre::LML_CRITICAL;
		break;
	}

	AELogManager::getSingleton().m_logs[_log]->logMessage(msg,level);
}

void AELogManager::setLogDetail(Ogre::LoggingLevel _ll,const string& _log /* = "default"*/)
{
	m_logs[_log]->setLogDetail(_ll);
}

void AELogManager::warn(const string& _in)
{
	log(ELL_WARN,_in);
}

void AELogManager::error(const string& _in)
{
	log(ELL_ERROR,_in);
}

void AELogManager::info(const string& _in)
{
	log(ELL_INFO,_in);
}

void AELogManager::print(const string& _in)
{
	log(ELL_NONE,_in);
}

END_ARETE_NAMESPACE